#!/bin/bash

# check for potential kill candidates (for debugging/information purposes)

#    (c) 2011 Donders Centre/Simon Oosthoek 
#
#    This file is part of PIM.
#
#    PIM is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 2 of the License, or
#    (at your option) any later version.
#
#    PIM is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with PIM.  If not, see <http://www.gnu.org/licenses/>.
#
if [ -f /opt/cluster/pim_lib ]
then
	. /opt/cluster/pim_lib
elif [ -f /mnt/opt/cluster/pim_lib ]
then
	. /mnt/opt/cluster/pim_lib
else
	echo "cannot load pim_lib" >&2
	exit 1
fi

# notify is at 10:00
# kill is at 10:55
notif_today=$(date -d 'today 10:00'  '+%s')
kill_today=$(date -d 'today 10:55'  '+%s')
notif_tomorrow=$(date -d 'tomorrow 10:00'  '+%s')
kill_tomorrow=$(date -d 'tomorrow 10:55'  '+%s')

if [ $# -gt 0 ]
then
	case "$1" in 
		all|kill|userkill|notified|extended|initial)	PIM_SELECT=$1
		;;
		*)	PIM_SELECT=false
		;;
	esac
else
	PIM_SELECT=false
fi

if [ $EPOCHNOW -ge $notif_today ]
then
	notif_time=$notif_tomorrow
else
	notif_time=$notif_today
fi

if [ $EPOCHNOW -ge $kill_today ]
then
	kill_time=$kill_tomorrow
else
	kill_time=$kill_today
fi

# check all pidfiles 
for pidfile in $pim_datadir/mentat*
do
	if [ ! -f "$pidfile" ]
	then
		echo "$PROG: $pidfile wasn't there" >&2
		continue
	fi

	#make sure we reset variables which we test for and which are not
	#always overwritten 
	pid_ownername="" 
	pid_notified="0"
	pid_randval=""
	pid_renewed="0"
	user_renew="0"
	user_kill="0"

	. "$pidfile"

	if [ -f "$pid_configused" ]
	then
		# source the config file used	
		. "$pid_configused"
	else
		echo "$pid_pid on $pid_machine for $pid_owner error: $pid_configused" >&2
		continue
	fi

	#skip if a user filter exists and applies to this user
	if [ -n "$only_for_groups" ]
	then
		if id -Gn $pid_owner|grep -Ew "$only_for_groups" >/dev/null
		then
			echo "user is member of a monitored group" >/dev/null
		else
			#echo "user $pid_owner group-ignored ($pid_machine $pid_pid $pid_elapsedtime)" >>$mailreport
			continue
		fi
	fi

	#skip if a user filter exists and applies to this user
	if [ -n "$only_for_users" ]
	then
		#check if owner in list of monitorable users
		if echo $pid_owner|grep -Ew "$only_for_users" >/dev/null
		then
			echo "user's processes will be managed" >/dev/null
		else
			#echo "user $pid_owner user-ignored ($pid_machine $pid_pid $pid_elapsedtime)" >>$mailreport
			continue
		fi
	fi
	
	#start state machine stuff
	state="initial"
	if [ $(( $pid_starttime + $time_initial*$SECPERDAY)) -gt $notif_time ]
	then
	#	echo $pid_starttime $(epoch2date $pid_starttime) $time_initial $notif_time $(( $pid_starttime + $time_initial*$SECPERDAY)) $(epoch2date $(( $pid_starttime + $time_initial*$SECPERDAY)) )
		continue
	fi
	# get user interaction file, if present
	if [ -f $pim_useract/${pid_machine}_$pid_pid ]
	then
		. $pim_useract/${pid_machine}_$pid_pid
	fi
	
	if [ "$user_renew" -gt 0 ]
	then	
		if [ $pid_renewed -lt $user_renew ]
		then 
			if [ "X$pid_randval" = "X$user_key" ]
			then
				# renew verified, set pid_renewed and renew process
				pid_renewed=$user_renew
			else 
				echo "renew failed $pid_pid for $pid_owner on $pid_machine"
			fi
		fi
	fi

	if [ $pid_notified -gt 0 -a $pid_renewed -gt $pid_notified ]
	then
		state="extended"
	elif [ $pid_notified -gt 0 ]
	then
		state="notified"
	fi
	
	if [ $state = "notified" -a \
	     $EPOCHNOW -gt $(($pid_notified + ($time_notified * $SECPERDAY) )) ]
	then
		# user has not responded in time
		state="kill"
	fi

	if [ "$user_kill" -gt "$user_renew" ]
	then
		if [ "$pid_randval" = "$user_key" ]
		then
			state="userkill"
		fi
	fi

	if exclude_user $pid_owner
	then
		state="EXCLUDED"
	fi

	unset actiontime
	unset actionrun
	unset actionstring

	case $PIM_SELECT in
		false) 	echo "no filter" >/dev/null ;;
		*)	if [ $state != $PIM_SELECT ]; then continue; fi ;;
	esac
	if [ $state = notified -o $state = kill ]
	then
		actiontime=$(( $pid_notified  + $time_notified*$SECPERDAY))
		actionrun=$kill_time
		actionstring="kill"
	elif [ $state = extended ]
	then
		actiontime=$(( $pid_renewed + $time_extended*$SECPERDAY ))
		actionrun=$notif_time
		actionstring="notify"
	elif [ $state = initial ]
	then
		actiontime=$(( $pid_starttime + $time_initial*$SECPERDAY ))
		actionrun=$notif_time
		actionstring="notify"
	else
		printf "%15s: %-10s (running %3d) state = %-10s\n" $(basename $pidfile) $pid_owner $(etime2day $pid_elapsedtime) $state 
		continue # skip the last bit below
	fi

	if [ $actiontime -le $actionrun ]
	then
		printf "%15s: %-10s (running %3d) state = %-10s" $(basename $pidfile) $pid_owner $(etime2day $pid_elapsedtime) $state 
		printf " ($actionstring from %s)" "$(echo $actiontime | awk '{print strftime("'"%F %R"'", $0)}')"
		printf " in %s hours\n" $(( ($actionrun - $EPOCHNOW) /3600))
	fi

done

